/**
 * <p>文件名:		SystemHelper.java</p>
 * <p>版权:		CopyrightTag</p>
 * <p>公司:		CompanyTag</p>
 * @author		周华彬(zhouhuabin@ctfo.com)
 */

package com.caits.lbs.framework.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.logging.log4j.Logger;

import com.caits.lbs.framework.log.CommonLogFactory;

/**
 * <p>
 * SystemHelper
 * </p>
 * <p>
 * TODO
 * </p>
 * @author 周华彬(zhouhuabin@ctfo.com)
 * @version 0.0.0
 *          <table style="border:1px solid gray;">
 *          <tr>
 *          <th width="100px">版本号</th>
 *          <th width="100px">动作</th>
 *          <th * width="100px">修改人</th>
 *          <th width="100px">修改时间</th>
 *          </tr>
 *          <!-- 以 Table 方式书写修改历史 -->
 *          <tr>
 *          <td>0.0.0</td>
 *          <td>创建类</td>
 *          <td>周华彬</td>
 *          <td>2008-7-14 下午02:25:30</td>
 *          </tr>
 *          <tr>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          <td>XXX</td>
 *          </tr>
 *          </table>
 */
public final class SystemUtils {

	/** 操作系统环境变量映射，使用set获取 */
	private static final Map<String, String> SYSTEM_ENV_MAP = new HashMap<String, String>();

	/** 日志记录器 */
	private static Logger _log = CommonLogFactory.getLog();

	/** 是否windows系列操作系统 */
	public static final boolean isWindows = ('\\' == File.separatorChar);

	/** 是否类unix系列操作系统，包括unix、solaris、linux等 */
	public static final boolean isUnix = ('/' == File.separatorChar);

	/** 获得系统属性集 */
	public static final Properties props = System.getProperties();
	/** jdk版本信息 */
	public static String JDK_MODEL = getPropertery("sun.arch.data.model");
	public static String JDK_VERSION = getPropertery("java.version");
	/** 操作系统名称架构版本 */
	public static String OS_NAME = getPropertery("os.name").toLowerCase();
	public static String OS_ARCH = getPropertery("os.arch");
	public static String OS_VERSION = getPropertery("os.version");
	/** 行分页符 */
	public static String OS_LINE_SEPARATOR = getPropertery("line.separator");
	/** 文件分隔符号 */
	public static String OS_FILE_SEPARATOR = getPropertery("file.separator");
	/** 主机的cpus数量 */
	public static final int OS_CPUS = Runtime.getRuntime().availableProcessors();
	static {
		initsystemEnvs();
	}

	/**
	 * 构造器
	 */
	private SystemUtils() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * FIXME
	 */
	public static void initsystemEnvs() {
		Process p = null;
		try {
			String OS = OS_NAME;
			if (OS.indexOf("windows") > -1) {
				p = Runtime.getRuntime().exec("cmd /c set");
			} else if (OS.indexOf("linux") > -1) {
				p = Runtime.getRuntime().exec("/bin/sh -c set");
			} else if (OS.indexOf("sunos") > -1) {
				p = Runtime.getRuntime().exec("/bin/sh -c set");
			} else {// 其它的操作系统可以自行处理，
				System.err.println("SystemHelper: 未知操作系统 os.name=" + OS);
				SYSTEM_ENV_MAP.clear();
			}
			if (p != null) {
				BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
				String line;
				while ((line = br.readLine()) != null) {
					int i = line.indexOf("=");
					if (i > -1) {
						String key = line.substring(0, i);
						String value = line.substring(i + 1);
						SYSTEM_ENV_MAP.put(key, value);
					}
				}

			}
		} catch (IOException e) {
			_log.error("SystemHelper: 获取系统环境失败，失败原因：" + e.getMessage(), e);
		}
	}

	/**
	 * 获取系统运行时，可以进行缓存，我们约定重新启动才需要重新加载，否则即使环境改变也不予更改，如果不然，必死无疑
	 * @return 必不为空，环境变量对应表
	 */
	public static Map<String, String> getSystemEnvs() {
		if (SYSTEM_ENV_MAP.isEmpty()) {
			initsystemEnvs();
		}
		return SYSTEM_ENV_MAP;
	}

	/**
	 * 获取指定名称的环境值
	 * @param envName 环境名，如果为空，返回必为null
	 * @return 当指定名称为空或者对应名称环境变量不存在时返回空
	 */
	public static String getSystemEnv(String envName) {
		if (StringUtils.isNullOrBlank(envName)) {
			if (SYSTEM_ENV_MAP.isEmpty()) {
				initsystemEnvs();
			}
			return SYSTEM_ENV_MAP.get(envName);
		}
		return null;
	}

	/**
	 * 输出系统内存使用情况
	 * @param writer 输出器1
	 * @param log 输出器2
	 */
	public static void printSystemMemory(final Writer writer,final Logger log) {
		// 不能频繁调用gc，可能带来性能问题
		// Runtime.getRuntime().gc();
		long total = Runtime.getRuntime().totalMemory() / (1024 * 1024);
		long free = Runtime.getRuntime().freeMemory() / (1024 * 1024);
		long max = Runtime.getRuntime().maxMemory() / (1024 * 1024);
		try {
			if (writer != null) {
				writer.write("当前内存使用" + total + "M,空闲" + free + "M,最大可用" + max + "M\r\n");
				writer.flush();
			}
			if (log != null && log.isInfoEnabled()) {
				log.info("当前内存使用" + total + "M,空闲" + free + "M,最大可用" + max + "M");
			}
		} catch (IOException e) {
			_log.error("输出系统占用内存错误,msg=" + e.getLocalizedMessage(), e);
		}

	}

	/**
	 * 获取属性的值
	 * @param propertyName
	 * @return
	 */
	public static String getPropertery(String propertyName) {
		return props.getProperty(propertyName);
	}

	/**
	 * * 方法 getLocalIp 获取本机ip地址 * @return
	 */
	public static String getLocalIp() {
		String localIp = "127.0.0.1";
		try {
			localIp = InetAddress.getLocalHost().getHostAddress();
		} catch (UnknownHostException e) {
			_log.info("获取服务器IP地址失败,msg:"+e.getLocalizedMessage());
		}
		return localIp;
	}

	/**
	 * *方法 getLocalMac 获取本机MAC地址 * @return
	 */
	public static String getLocalMac() {
		String mac = null;
		try {
			// System.out.println(os);
			if (isWindows) {
				// 本地是windows
				mac = getWindowsMACAddress();
				// System.out.println(mac);
			} else {
				// 本地是非windows系统 一般就是unix
				mac = getUnixMACAddress();
				// System.out.println(mac);
			}
		} catch (Exception e) {
			_log.info("获取服务器MAC地址失败!", e);
		}
		return mac;
	}

	/**
	 * * 获取unix网卡的mac地址. 非windows的系统默认调用本方法获取.如果有特殊系统请继续扩充新的取mac地址方法. * *
	 * @return mac地址
	 */
	public static String getUnixMACAddress() {
		String mac = null;
		BufferedReader bufferedReader = null;
		Process process = null;
		try {
			process = Runtime.getRuntime().exec("/sbin/ifconfig eth0");
			// linux下的命令，一般取eth0作为本地主网卡 显示信息中包含有mac地址信息
			bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
			String line = null;
			int index = -1;
			while ((line = bufferedReader.readLine()) != null) {
				index = line.toLowerCase().indexOf("hwaddr");// 寻找标示字符串[hwaddr]
				if (index >= 0) {// 找到了
					mac = line.substring(index + "hwaddr".length() + 1).trim();
					// 取出mac地址并去除2边空格
					break;
				}
			}
		} catch (IOException e) {
			_log.info("获取服务器MAC地址失败!", e);
		} finally {
			try {
				if (bufferedReader != null) {
					bufferedReader.close();
				}
			} catch (IOException e) {
				_log.info("关闭输出流失败!", e);
			}
			bufferedReader = null;
			process = null;
		}
		return mac;
	}

	/** * 获取widnows网卡的mac地址. * @return mac地址 */
	public static String getWindowsMACAddress() {
		String mac = null;
		BufferedReader bufferedReader = null;
		Process process = null;
		try {
			process = Runtime.getRuntime().exec("ipconfig /all");
			// windows下的命令，显示信息中包含有mac地址信息
			bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
			String line = null;
			int index = -1;
			while ((line = bufferedReader.readLine()) != null) {
				index = line.toLowerCase().indexOf("physical address");
				// 寻找标示字符串[physical address]
				if (index >= 0) {// 找到了
					index = line.indexOf(":");// 寻找":"的位置
					if (index >= 0) {
						mac = line.substring(index + 1).trim();// 取出mac地址并去除2边空格
					}
					break;
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (bufferedReader != null) {
					bufferedReader.close();
				}
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			bufferedReader = null;
			process = null;
		}
		return mac;
	}

	/**
	 * 获取jdk版本信息
	 * @return
	 */
	public static String getJDKVersion() {
		return JDK_VERSION + "_x" + JDK_MODEL;
	}

	/**
	 * 获取操作系统版本信息
	 * @return
	 */
	public static String getOSVersion() {
		return OS_NAME + "_" + OS_VERSION + "_" + OS_ARCH;
	}
	
	public static String getUUID() {   
        GUID uuid = GUID.randomUUID();   
        String str = uuid.getShortString();   
        // 去掉"-"符号   
//        String temp =  str.replaceAll("\\-", "");
//        String temp = str.substring(0, 8) + str.substring(9, 13) + str.substring(14, 18) + str.substring(19, 23) + str.substring(24);   
        return str;   
    }   
	
	/**
	 * FIXME
	 * @param args
	 */
	public static void main(String[] args) {
		printSystemMemory(new PrintWriter(System.out), _log);
		StringBuilder sb = new StringBuilder();
		StringUtils.map2String(sb, "userEnvs", props);
		_log.info("get system properties:" + sb.toString());
		sb.delete(0, sb.length() - 1);
		StringUtils.map2String(sb, "userMap", getSystemEnvs());
		_log.info("get user envs:" + sb.toString());
		_log.info("get local ip:" + getLocalIp());
		_log.info("get local mac:" + getLocalMac());
		_log.info("get OSVersion:" + getOSVersion());
		_log.info("get JDKVersion:" + getJDKVersion());
		_log.info("start getUUID.");
		//测试UUID得出1百万次1.5秒,GUID是1.2秒
		for(int i =0;i<1000000;i++){
			String aaa= getUUID();
		}
		_log.info("end getUUID.");
	}

}
